(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

创建分级状态机

Description: 本教程教你如何嵌套不同的状态机,创建分级状态机。

Tutorial Level: BEGINNER

Next Tutorial: 从SMACH状态机调用行为

创建一组状态

对于这个示例,我们创建一组状态,每一个包含指定的一组输出(outcomes),输出键(input keys)和输出键(output keys)。

   1   # State Foo
   2   class Foo(smach.State):
   3      def __init__(self, outcomes=['outcome1', 'outcome2'])
   4      
   5      def execute(self, userdata):
   6         return 'outcome1'
   7 
   8 
   9   # State Bar
  10   class Bar(smach.State):
  11      def __init__(self, outcomes=['outcome1'])
  12      
  13      def execute(self, userdata):
  14         return 'outcome4'
  15 
  16 
  17   # State Bas
  18   class Bas(smach.State):
  19      def __init__(self, outcomes=['outcome3'])
  20      
  21      def execute(self, userdata):
  22         return 'outcome3'

创建分级状态机

我们创建一个顶级状态机,并开始向它添加状态。我们添加的一个状态是另一个状态机:

   1    # Create the top level SMACH state machine
   2     sm_top = smach.StateMachine(outcomes=['outcome5'])
   3 
   4     # Open the container
   5     with sm_top:
   6 
   7         smach.StateMachine.add('BAS', Bas(),
   8                                transitions={'outcome3':'SUB'})
   9 
  10         # Create the sub SMACH state machine 
  11         sm_sub = smach.StateMachine(outcomes=['outcome4'])
  12 
  13         # Open the container 
  14         with sm_sub:
  15 
  16             # Add states to the container 
  17             smach.StateMachine.add('FOO', Foo(),
  18                                    transitions={'outcome1':'BAR', 
  19                                                 'outcome2':'outcome4'})
  20             smach.StateMachine.add('BAR', Bar(),
  21                                    transitions={'outcome1':'FOO'})
  22 
  23         smach.StateMachine.add('SUB', sm_sub,
  24                                transitions={'outcome4':'outcome5'})

结果是这样的。唯一需要注意的是,每个状态机也是一个正常状态。因此,你可以将状态机添加到另一个状态机,就像将状态添加到状态机一样。因此,处理用户数据与处理分级状态机没有什么不同:子状态机指定输入和输出键,当你将子状态机添加到顶层状态机时,它们会被重新映射。

sm_expanded.png

示例

executive_smach_tutorials包中可以找到可运行的完整示例.

https://raw.githubusercontent.com/eacousineau/executive_smach_tutorials/hydro-devel/smach_tutorials/examples/state_machine_nesting2.py

   1 #!/usr/bin/env python
   2 
   3 import roslib; roslib.load_manifest('smach_tutorials')
   4 import rospy
   5 import smach
   6 import smach_ros
   7 
   8 # define state Foo
   9 class Foo(smach.State):
  10     def __init__(self):
  11         smach.State.__init__(self, outcomes=['outcome1','outcome2'])
  12         self.counter = 0
  13 
  14     def execute(self, userdata):
  15         rospy.loginfo('Executing state FOO')
  16         if self.counter < 3:
  17             self.counter += 1
  18             return 'outcome1'
  19         else:
  20             return 'outcome2'
  21 
  22 
  23 # define state Bar
  24 class Bar(smach.State):
  25     def __init__(self):
  26         smach.State.__init__(self, outcomes=['outcome1'])
  27 
  28     def execute(self, userdata):
  29         rospy.loginfo('Executing state BAR')
  30         return 'outcome1'
  31         
  32 
  33 
  34 # define state Bas
  35 class Bas(smach.State):
  36     def __init__(self):
  37         smach.State.__init__(self, outcomes=['outcome3'])
  38 
  39     def execute(self, userdata):
  40         rospy.loginfo('Executing state BAS')
  41         return 'outcome3'
  42 
  43 
  44 
  45 
  46 def main():
  47     rospy.init_node('smach_example_state_machine')
  48 
  49     # Create the top level SMACH state machine
  50     sm_top = smach.StateMachine(outcomes=['outcome5'])
  51     
  52     # Open the container
  53     with sm_top:
  54 
  55         smach.StateMachine.add('BAS', Bas(),
  56                                transitions={'outcome3':'SUB'})
  57 
  58         # Create the sub SMACH state machine
  59         sm_sub = smach.StateMachine(outcomes=['outcome4'])
  60 
  61         # Open the container
  62         with sm_sub:
  63 
  64             # Add states to the container
  65             smach.StateMachine.add('FOO', Foo(), 
  66                                    transitions={'outcome1':'BAR', 
  67                                                 'outcome2':'outcome4'})
  68             smach.StateMachine.add('BAR', Bar(), 
  69                                    transitions={'outcome1':'FOO'})
  70 
  71         smach.StateMachine.add('SUB', sm_sub,
  72                                transitions={'outcome4':'outcome5'})
  73 
  74     # Execute SMACH plan
  75     outcome = sm_top.execute()
  76 
  77 
  78 
  79 if __name__ == '__main__':
  80     main()

运行示例:

$ roscd smach_tutorials
$ ./examples/state_machine_nesting2.py 

Wiki: cn/smach/Tutorials/Create a hierarchical state machine (last edited 2018-03-10 03:31:39 by Playfish)